package com.cloud.punish.interfaces;

import java.util.ArrayList;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.netflix.feign.FeignClient;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;

import com.cloud.punish.common.config.FeignConfiguration;
import com.cloud.punish.tasklist.bean.Part;
import com.cloud.punish.tasklist.bean.ProcDef;
import com.cloud.punish.workflow.bean.WfActDef;
import com.cloud.punish.workflow.bean.WfActEvent;

import feign.hystrix.FallbackFactory;

@FeignClient(value = "FREEFLOW", configuration = FeignConfiguration.class, fallbackFactory = FeignClientFreeFlowFallbackFactory.class)
public interface FeignClientFreeflow {
	@RequestMapping(value = "freeflow/api/interface/listprocbybiz", method = RequestMethod.GET)
	public List<ProcDef> listProcDefByBizId(@RequestParam("bizId") long bizId);

	@RequestMapping(value = "freeflow/api/interface/loadpartsbyactdef", method = RequestMethod.GET)
	public List<Part> loadPartsByActDef(@RequestParam("actDefId") long actDefId);

	@RequestMapping(value = "freeflow/api/interface/loadpartsbyprocdef", method = RequestMethod.GET)
	public List<Part> loadPartsByProcDef(@RequestParam("procDefId") long procDefId);

	@RequestMapping(value = "freeflow/api/interface/loadprocactparts", method = RequestMethod.GET)
	public List<ProcDef> loadProcActParts(@RequestParam("bizId") int bizId);

	@RequestMapping(value = "freeflow/api/interface/loadprocactevents", method = RequestMethod.GET)
	public List<WfActEvent> loadProcActEvents(@RequestParam("actDefId") long actDefId);

	@RequestMapping(value = "freeflow/api/interface/loadstartactbyprocandpart", method = RequestMethod.GET)
	public WfActDef loadStartActByProcAndPart(@RequestParam("procDefId") long procDefId,
			@RequestParam("parts") String parts);

	@RequestMapping(value = "freeflow/api/interface/loadactdef", method = RequestMethod.GET)
	public WfActDef loadProcActDef(@RequestParam("actDefId") Long actDefId);

	@RequestMapping(value = "freeflow/api/interface/searchnextactdefs", method = RequestMethod.GET)
	public List<WfActDef> searchNextActDefs(@RequestParam("actDefId") Long actDefId);

}

@Component
class FeignClientFreeFlowFallbackFactory implements FallbackFactory<FeignClientFreeflow> {
	private static final Logger LOGGER = LoggerFactory.getLogger(FeignClientFreeFlowFallbackFactory.class);

	@Override
	public FeignClientFreeflow create(Throwable cause) {
		return new FeignClientFreeflow() {
			@Override
			public List<ProcDef> listProcDefByBizId(long bizId) {
				if (FeignClientFreeFlowFallbackFactory.LOGGER.isDebugEnabled()) {
					FeignClientFreeFlowFallbackFactory.LOGGER
							.debug("listProcDefByBizCode fallback; reason was:" + cause);
				}
				List<ProcDef> def = new ArrayList<ProcDef>();
				return def;
			}

			@Override
			public List<Part> loadPartsByActDef(long actDefId) {
				if (FeignClientFreeFlowFallbackFactory.LOGGER.isDebugEnabled()) {
					FeignClientFreeFlowFallbackFactory.LOGGER.debug("loadPartsByActDef fallback; reason was:" + cause);
				}
				List<Part> parts = new ArrayList<Part>();
				return parts;
			}

			@Override
			public List<Part> loadPartsByProcDef(long procDefId) {
				if (FeignClientFreeFlowFallbackFactory.LOGGER.isDebugEnabled()) {
					FeignClientFreeFlowFallbackFactory.LOGGER.debug("loadPartsByProcDef fallback; reason was:" + cause);
				}
				List<Part> parts = new ArrayList<Part>();
				return parts;
			}

			@Override
			public List<ProcDef> loadProcActParts(int bizId) {
				return new ArrayList<ProcDef>();
			}

			@Override
			public List<WfActEvent> loadProcActEvents(long actDefId) {
				return new ArrayList<WfActEvent>();
			}

			@Override
			public WfActDef loadStartActByProcAndPart(long procDefId, String parts) {
				if (FeignClientFreeFlowFallbackFactory.LOGGER.isDebugEnabled()) {
					FeignClientFreeFlowFallbackFactory.LOGGER
							.debug("getStartActByProcAndPart fallback; reason was:" + cause);
				}
				return null;

			}

			@Override
			public WfActDef loadProcActDef(Long actDefId) {
				if (FeignClientFreeFlowFallbackFactory.LOGGER.isDebugEnabled()) {
					FeignClientFreeFlowFallbackFactory.LOGGER.debug("loadProcActDef fallback; reason was:" + cause);
				}
				return null;
			}

			@Override
			public List<WfActDef> searchNextActDefs(Long actDefId) {
				if (FeignClientFreeFlowFallbackFactory.LOGGER.isDebugEnabled()) {
					FeignClientFreeFlowFallbackFactory.LOGGER.debug("searchNextActDefs fallback; reason was:" + cause);
				}
				return null;
			}

		};
	}
}
